package cn.wolfcode.ss.config;

import cn.wolfcode.ss.handler.MyAuthenticationSuccessHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;

// 使用这个配置后，不会在使用控制台生成的默认用户user和随即密码
// extends WebSecurityConfigurerAdapter继承这个就可以自定义自己的登陆页面

// 总结：使用自定义的登陆和登陆处理
// 1.继承WebSecurityConfigurerAdapter
// 2.重写configure方法

// 支持注解方式进行授权 + 鉴权
// prePostEnabled=true 表示支持：@PreAuthorize 使用
// @EnableGlobalMethodSecurity(securedEnabled = true,prePostEnabled = true)
// @Configuration
public class SpringSecurityConfig_bak extends WebSecurityConfigurerAdapter {
    // 基于内存-获取用户信息
    // UserDetailsService -- springSecurity 提供专门用于加载用户信息服务层接口
    @Bean
    public UserDetailsService userDetailsService(){
        InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
        // authorities -- 等价于 permission
        // todo: 构建者模式 --- xxx.build()
        manager.createUser(User
                .withUsername("diaomao")
                .password("666")
                // .authorities("p1")
                // .authorities("dept:insert","dept:update")
                // .roles("dept_mgr")
                .roles("DEPT_MGR") // 会自动添加ROLE_前缀
                .build());
        manager.createUser(User.withUsername("asan").password("666").authorities("p2").build());
        return manager;
    }

    @Bean
    public PasswordEncoder passwordEncoder(){
        return NoOpPasswordEncoder.getInstance();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // super.configure(http); // 去掉ss默认登陆认证，使用自定义的--需要定义所有拦截与认证操作

        // 禁用csrf安全保护
        http.csrf().disable();

        // url路径权限控制
        http.authorizeRequests()
                // .antMatchers("/depts/insert").hasAnyRole("dept_mgr","hr")
                // .antMatchers("/depts/update").hasRole("dept_mgr")
                // .antMatchers("/depts/delete").hasRole("hr")
                // .antMatchers("/depts/list").hasRole("hr")
                // .antMatchers("/depts/insert").hasAuthority("dept:insert")
                // .antMatchers("/depts/update").hasAuthority("dept:update")
                // .antMatchers("/depts/delete").hasAuthority("dept:delete")
                // .antMatchers("/depts/list").hasAuthority("dept:list")
                // 匹配 /login permitAll --全部放行
                // .antMatchers("/userLogin","/login.html").permitAll()
                .antMatchers("/userLogin").permitAll()
                .antMatchers("/login.html").permitAll()
                .antMatchers("/logoutSuccess").permitAll()
                // .antMatchers("/login","/login.html").permitAll()
                .antMatchers("/fail").permitAll()
                // anyRequest 匹配所有请求, authenticated 认证拦截
                .anyRequest().authenticated();

        // 用户登陆控制
        http.formLogin()
            // 登陆页面是自己定义的那个
            .loginPage("/login.html")
            // 登陆处理的action是/login
            // .loginProcessingUrl("/login")
            .loginProcessingUrl("/userLogin")
            .usernameParameter("uname") // 修改登陆用户名参数
            .passwordParameter("pwd") // 修改密码的参数key
            // .successForwardUrl("/success") // 登陆成功跳转
            // 登陆成功之后处理器--登陆成功之后，自定义逻辑-前后端分离项目--定制：返回json格式
            .successHandler(new MyAuthenticationSuccessHandler())
            // .failureForwardUrl("/fail"); // 登陆失败跳转
            .failureHandler((request, response, e)-> {
                response.setContentType("application/json;charset=utf-8");
                String data = "{\"code\":200,\"msg\":\"登陆失败\",\"data\":"+e.getMessage()+"}";
                response.getWriter().write(data);
            });

        // 用户登出控制
        http.logout()
            .logoutUrl("/userLogout") //默认是/logout
            // .logoutSuccessUrl("/logoutSuccess")
            .logoutSuccessHandler((request, response, authentication) -> {
                response.setContentType("application/json;charset=utf-8");
                String data = "{\"code\":200,\"msg\":\"登出成功\",\"data\":{}}";
                response.getWriter().write(data);
            });

        // 异常处理
        http.exceptionHandling()
                // 当鉴权失败，跳转的页面
                // .accessDeniedPage("/nopermission.html");
                .accessDeniedHandler((request, response, e) -> {
                    response.setContentType("application/json;charset=utf-8");
                    String data = "{\"code\":403,\"msg\":\"没有权限\",\"data\":"+e.getMessage()+"}";
                    response.getWriter().write(data);
                });
    }
}
